<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>vue</title>
</head>

<body>
    <script src="https://unpkg.com/vue@2.6.14/dist/vue.js"></script>
    <div id="app">
        <div v-draggable:absolute.ctrl="styleObj"></div>
    </div>
    <script>
        //定义一个指令 名字叫draggable,再定义一个对象，里面编写很多钩子函数
        //def 指的就是指令的定义对象
        //name: "draggable" 就是指令的名字，就是v-后面这个单词
        //rawName: "v-draggable" 就是加上前面的v-的原生的指令名称
        //modifiers: {disable:true} 指令修饰符
        Vue.directive('draggable', {
            //这就是一个钩子函数，你不需要自己调用此函数，只需要写好放在这就可以
            bind(el, binding) {
                console.log(binding);
                //如果有disable这个修饰符，那就直接返回，不再去支持拖动
                if (binding.modifiers.disable) return;
                let isCtrl = false;
                //获取指令的参数
                el.style.position = binding.arg;
                //通过binding.value获取样式对象
                let { value: styleObj } = binding;//let styleObj=binding.value;
                //把样式对象里的样式赋给真实的DOM元素
                for (let key in styleObj) {
                    el.style[key] = styleObj[key];
                }
                let isDragging = false;//当前是否正在拖拽
                let offsetX, offsetY;
                //给当前这个DIV添加鼠标按下的事件
                el.addEventListener('mousedown', (event) => {
                    //如果需要按下ctrl键，但当前并没有按下ctrl键的话就不能拖
                    if (binding.modifiers.ctrl && !isCtrl) {
                        return;
                    }
                    offsetX = event.offsetX;
                    offsetY = event.offsetY;
                    isDragging = true;
                });
                //当我们移动鼠标的时候，计算元素的最新的位置 
                el.addEventListener('mousemove', (event) => {
                    if (isDragging) {
                        el.style.left = event.clientX - offsetX + 'px';
                        el.style.top = event.clientY - offsetY + 'px';
                    }
                });
                //当松下的时候，停止拖动
                el.addEventListener('mouseup', (event) => {
                    isDragging = false;
                });
                el.onKeyDown = (event) => {
                    if (event.key === 'Control') isCtrl = true;
                }
                //监听按键事件，当按下ctrl键的话就把isCtrl=true
                document.addEventListener('keydown', el.onKeyDown);
                el.onKeyUp = (event) => {
                    if (event.key === 'Control') isCtrl = false;
                }
                //监听按键事件，当松开ctrl键的话就把isCtrl=false
                document.addEventListener('keyup', el.onKeyUp);
            },
            unbind(el, binding) {
                console.log('unbind')
                document.removeEventListener('keydown', el.onKeyDown);
                document.removeEventListener('keyup', el.onKeyUp);
             }

        });
        var vm = new Vue({
            el: '#app',
            data: {
                styleObj: { width: '100px', height: '100px', backgroundColor: 'green' }
            }
        })
        vm.$destroy();
    </script>
</body>

</html>